<template>
  <div id="article">
    <Loading v-if="!article.body"></Loading>
    <Header></Header>
    <div class="content-wrapper">
      <div class="cover-image">
        <img :src="article.coverImg" alt="封面图" />
      </div>
      <h1 class="title">{{ article.title }}</h1>
      <div v-html="article.body" class="body"></div>
      <div class="bottom isfix">
        <div
          :class="status ? 'vote vote-up' : 'vote'"
          @click="toggle"
          ref="voteRef"
        >
          <i class="iconfont icon-up"
            ><span>点赞 {{ voteNum }}</span></i
          >
        </div>
        <div class="comment-num" @click="commentClick">
          <i class="iconfont icon-pinglun1-copy"
            ><span>{{ comments.length }}条评论</span></i
          >
        </div>
        <div class="share">
          <i class="iconfont icon-fenxiang"><span>分享</span></i>
          <canvas ref="canvasRef"></canvas>
        </div>
        <div class="auth">
          <i class="iconfont icon-zuozhe"
            ><span>{{ article.author }}</span></i
          >
        </div>
        <div class="time">
          <i class="iconfont icon-time"
            ><span>{{ formatTime(article.createdAt) }}</span></i
          >
        </div>
      </div>
      <div class="comment" ref="commentRef">
        <div class="top-bar">
          <div class="avatar-upload">
            <input
              type="file"
              accept="images/*"
              @change="avatarChange"
              ref="avatarRef"
            />
            <img :src="visitorInfo.avatarUrl" alt="上传头像" />
          </div>
          <div class="visitor-name">
            <input
              type="text"
              required="required"
              maxlength="15"
              placeholder="请输入昵称"
              @keyup="visitorNameKeyUp"
              v-model="visitorInfo.visitorName"
            />
          </div>
          <div class="email">
            <input
              type="text"
              maxlength="20"
              placeholder="邮箱(可选)"
              v-model="visitorInfo.email"
            />
          </div>
        </div>
        <div class="line"></div>
        <div class="comment-input">
          <div
            ref="divTextRef"
            contenteditable="true"
            class="divText"
            @input="inputDiv($event)"
          >
            {{ divText }}
          </div>
          <button @click="sendClick">发布</button>
        </div>
        <div class="commentsList" v-if="comments.length">
          <div
            class="comment-item"
            v-for="(item, index) in comments"
            :key="index"
          >
            <div class="comment-item-info">
              <div class="comment-avatar">
                <img :src="item.visitor_id.avatarUrl" alt="" />
              </div>
              <div class="comment-visitorname">
                {{ item.visitor_id.visitorName }}
              </div>
              <div class="comment-date">{{ formatTime(item.createdAt) }}</div>
            </div>
            <div class="comment-content">{{ item.content }}</div>
          </div>
        </div>
        <div v-else class="nocomment">暂无评论...</div>
      </div>
    </div>
    <ScrollToTop />
  </div>
</template>

<script >
import {
  defineComponent,
  onMounted,
  reactive,
  toRefs,
  ref,
  watch,
  onUnmounted,
} from "vue";
import Header from "../components/Header";
import http from "../services/http";
import { throttle, formatTime, imgLazyLoad } from "../libs/toolsLib";
import { messageBox } from "../libs/WeisonUI/Modal/index.js";
import QRCode from "qrcode";
export default defineComponent({
  name: "Article",
  components: { Header },
  props: {
    id: { required: true },
  },

  setup(props) {
    const state = reactive({
      article: {},
      status: false,
      voteNum: 0,
      comments: [],
      visitorInfo: {},
      imgList: [],
    });
    const divText = ref("");
    const divTextRef = ref(null);
    const voteRef = ref(null);
    const avatarRef = ref(null);
    const commentRef = ref(null);
    const canvasRef = ref(null);
    const getData = async () => {
      //获取文章详情
      const detailRes = await http.get(`article/${props.id}`);
      state.article = detailRes.data;
      const body = state.article.body;
      const reg = /<img\s(src=.*?)>/gm;
      state.imgList = body.match(reg);
      state.article.body = body.replace(
        reg,
        '<div class="img-container"><img class="lazyImg" src="https://www.weison-zhong.cn/uploads/loading.gif"></div>'
      );
      //获取点赞情况
      const statusRes = await http.get("actions/status", {
        params: {
          type: "Article",
          object: state.article._id,
          name: "like",
        },
      });
      state.status = statusRes.data.status;
      state.voteNum = statusRes.data.voteNum;
    };
    //获取访客信息
    const getVisitorInfo = async () => {
      const visitorRes = await http.get("visitor");
      const visitor_id = localStorage.getItem("visitor_id");
      if (visitor_id) {
        state.visitorInfo = visitorRes.data;
      } else {
        localStorage.setItem("visitor_id", visitorRes.data.newVisitorInfo._id);
        state.visitorInfo = visitorRes.data.newVisitorInfo;
      }
    };
    //获取评论列表
    const getComments = async () => {
      const commentsRes = await http.get(`comments/${props.id}`);
      state.comments = commentsRes.data;
    };
    getComments();
    getVisitorInfo();
    onMounted(() => {
      getData();
      //生成分享弹出二维码
      QRCode.toCanvas(canvasRef.value, window.location.href);
      //图片懒加载
      document.addEventListener("scroll", scrollCb);
    });

    watch(
      () => {
        return state.imgList;
      },
      (imgList) => {
        setTimeout(() => {
          imgLazyLoad(imgList);
        }, 1000);
      }
    );
    function scrollCb() {
      imgLazyLoad(state.imgList);
    }
    const inputDiv = (e) => {
      divText.value = e.target.innerText;
    };
    //切换点赞状态
    const toggle = async () => {
      const res = await http.post("actions/toggle", {
        type: "Article",
        object: state.article._id,
        name: "like",
      });
      state.status = res.data.status;
      state.voteNum = res.data.voteNum;
    };
    //发送评论
    const send = async () => {
      if (!state.visitorInfo.visitorName) {
        messageBox("昵称不能为空", 1500);
        return;
      } else if (!divText.value) {
        messageBox("评论内容不能为空", 1500);
        return;
      }
      await http.post("comments", {
        type: "article",
        object: state.article._id,
        content: divText.value,
      });
      await http.post("visitor/edit", state.visitorInfo);
      getComments();
      getVisitorInfo();
      messageBox("发送成功", 1500);
    };
    const sendClick = throttle(send, 5000, "不可以重复刷屏噢");
    //限制昵称字符串格式
    const visitorNameKeyUp = () => {
      const reg = /[^-A-z0-9\u4e00-\u9fa5]+/g;
      state.visitorInfo.visitorName = state.visitorInfo.visitorName.replace(
        reg,
        ""
      );
    };
    //头像上传
    const avatarChange = () => {
      const file = avatarRef.value.files[0];
      const type = file.type.split("/")[1];
      if (["jpeg", "png", "jpg"].indexOf(type) === -1) {
        messageBox("抱歉，只支持jpg、jpeg和png格式的图片", 3000);
        return;
      }
      if (file.size > 1024 * 1024 * 2) {
        messageBox("抱歉，图片不能超过2M", 3000);
      }
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = (e) => (state.visitorInfo.avatarUrl = e.target.result);
    };
    //点击评论数量滑动到评论列表
    const commentClick = () => {
      commentRef.value.scrollIntoView({ behavior: "smooth" });
    };
    onUnmounted(() => {
      document.removeEventListener("scroll", scrollCb);
    });
    return {
      ...toRefs(state),
      inputDiv,
      divText,
      divTextRef,
      toggle,
      voteRef,
      sendClick,
      avatarChange,
      avatarRef,
      formatTime,
      commentClick,
      commentRef,
      canvasRef,
      visitorNameKeyUp,
    };
  },
});
</script>